package com.alibaba.citrus.cr.price.repository.impl;

import com.alibaba.acm.shaded.com.alibaba.metrics.StringUtils;
import com.alibaba.citrus.cr.common.annotation.RepositoryInvoker;
import com.alibaba.citrus.cr.price.adapter.CreditQueryAdapter;
import com.alibaba.citrus.cr.price.repository.CreditQueryRepository;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcorder.model.dto.*;
import com.epoch.app.bcorder.service.BaseDataService;
import com.epoch.app.crplatformenhance.api.group.scitemgroupquery.service.ScItemGroupQueryService;
import com.epoch.app.crplatformenhance.channel.service.ChannelService;
import com.epoch.app.crplatformenhance.credit.model.Credit;
import com.epoch.app.crplatformenhance.credit.service.CreditService;
import com.epoch.app.crplatformenhance.domain.customeraddress.dto.LoadCustomerAddressRequest;
import com.epoch.app.crplatformenhance.domain.customeraddress.model.CustomerAddress;
import com.epoch.app.crplatformenhance.domain.customeraddress.service.CustomerAddressService;
import com.epoch.app.crplatformenhance.dto.request.QueryScItemGroupRequest;
import com.epoch.app.crplatformenhance.dto.response.ScItemGroupResponse;
import com.epoch.app.crplatformenhance.model.dto.ChannelResponse;
import com.epoch.app.crplatformenhance.model.dto.CreditLoadListRequest;
import com.epoch.app.crplatformenhance.model.dto.QueryChannelRequest;
import com.epoch.app.crpricecenter.api.creditquery.dto.QueryCompanyToGroupCreditListRequest;
import com.epoch.app.crpricecenter.model.dto.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: qianlei
 * @create: 2021/10/29 01:22
 */
@Repository
public class CreditQueryRepositoryImpl implements CreditQueryRepository {

    private static Log log = Log.getLogger(CreditQueryRepositoryImpl.class);

    @Autowired
    CreditQueryAdapter creditQueryAdapter;
    @Autowired
    ScItemGroupQueryService scItemGroupQueryService;
    @Autowired
    CustomerAddressService customerAddressService;
    @Autowired
    BaseDataService baseDataService;
    @Autowired
    ChannelService channelService;
    @Resource
    private CreditService creditService;
//    @Resource
//    private PropertyProcessManager propertyProcessManager;

    @Override
    @RepositoryInvoker(printLog = true)
    public List<CreditInfoSDO> queryCreditList(List<CreditInfoSDO> creditInfoList) {
        return queryCreditList(creditInfoList, true);
    }

    @Override
    public List<CreditInfoSDO> batchQueryCreditList(@NotNull List<CreditQueryRequest> requestList) {
        //batch query organization
        // Organization code inner to outer
        Map<String, String> orgInnerToOuterCodeMap=new HashMap<>();
        // Organization code outer to inner
        Map<String, String> orgOuterToInnerCodeMap=new HashMap<>();
        List<String> orgIds = requestList.stream().map(CreditQueryRequest::getInnerOrganizationCode).collect(Collectors.toList());
        BaselineGetOrganizationByIdsAllRequest organizationByCodes2Request = new BaselineGetOrganizationByIdsAllRequest();
        organizationByCodes2Request.setIds(orgIds);
        BaselineGetOrganizationByIdsAllResponse orgResponse = baseDataService.baselineGetOrganizationByIdsAll(organizationByCodes2Request);
        if (orgResponse.getSuccess() && CollectionUtils.isNotEmpty(orgResponse.getResult())){
            orgInnerToOuterCodeMap = orgResponse.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getId, OrganizationSDO::getOutCode, (v1, v2) -> v1));
            orgOuterToInnerCodeMap = orgResponse.getResult().stream().collect(Collectors.toMap(OrganizationSDO::getOutCode,OrganizationSDO::getId , (v1, v2) -> v1));
        }
        for (CreditQueryRequest o : requestList) {
            if (orgInnerToOuterCodeMap.containsKey(o.getInnerOrganizationCode())){
                o.setOrganizationCode(orgInnerToOuterCodeMap.get(o.getInnerOrganizationCode()));
            }
        }

        List<CreditInfoSDO> creditInfoSDOS = requestList.stream().map(o -> {
            CreditInfoSDO creditInfoSDO = new CreditInfoSDO();
            creditInfoSDO.setOrganizationCode(o.getOrganizationCode());
            creditInfoSDO.setCustomerCode(o.getCustomerCode());
            creditInfoSDO.setItemGroupCode(o.getItemGroupCode());
            creditInfoSDO.setChannelCode(o.getChannelCode());
            return creditInfoSDO;
        }).collect(Collectors.toList());

        BatchCreditQueryRequest queryRequest = new BatchCreditQueryRequest();
        queryRequest.setCreditQueryList(creditInfoSDOS);
        List<CreditInfoSDO> result = creditQueryAdapter.sapBatchCreditQuery(queryRequest);
        if (CollectionUtils.isNotEmpty(result)){
            for (CreditInfoSDO o : result) {
                if (orgOuterToInnerCodeMap.containsKey(o.getOrganizationCode())) {
                    o.setInnerOrganizationCode(orgOuterToInnerCodeMap.get(o.getOrganizationCode()));
                }
            }
        }
        return result;
    }

    @Override
    @RepositoryInvoker(printLog = true)
    public List<CreditInfoSDO> queryCreditList(List<CreditInfoSDO> creditInfoList, boolean enhance) {
        if(CollectionUtils.isEmpty(creditInfoList) || creditInfoList.size()!=1){
            return new ArrayList<>();
        }
        try {
            BatchCreditQueryRequest queryRequest = new BatchCreditQueryRequest();
            queryRequest.setCreditQueryList(creditInfoList);
            List<CreditInfoSDO> result = creditQueryAdapter.sapCreditQuery(queryRequest);
            CreditInfoSDO queryInfo = creditInfoList.get(0);
            result = Nullable.stream(result).map(x->{
                x.setSuccess(Objects.equals(x.getCode(), "0"));
                if (enhance && StringUtils.isNotBlank(queryInfo.getOrganizationCode())) {
                    //根据内部编码获取组织名称
//                    Map<String, String> organizationOutCodeAndDescMap = propertyProcessManager
//                            .getPropertyProcess(DimensionPropertyEnum.ORG_SALES_ORGANIZATION_CODE.getKey())
//                            .obtainCodeAndDescMap(Lists.newArrayList(queryInfo.getOrganizationCode()), true);
//                    x.setOrganizationName(organizationOutCodeAndDescMap.get(queryInfo.getOrganizationCode()));

                    BaselineGetOrganizationByCodes2Request request = new BaselineGetOrganizationByCodes2Request();
                    request.setIds(Lists.newArrayList(queryInfo.getOrganizationCode()));
                    BaselineGetOrganizationByCodes2Response response = baseDataService.baselineGetOrganizationByCodes2(request);
                    if (response.getSuccess() && CollectionUtils.isNotEmpty(response.getResult())){
                        OrganizationSDO organizationSDO = response.getResult().get(0);
                        x.setOrganizationName(organizationSDO.getName());
                    }
                }

                if (enhance && StringUtils.isNotBlank(queryInfo.getChannelCode())) {
                    QueryChannelRequest queryChannelsRequest = new QueryChannelRequest();
                    queryChannelsRequest.setChannelCode(queryInfo.getChannelCode());
                    //调用查询渠道信息
                    Result<ChannelResponse> channelResult = channelService.queryChannelDetail(queryChannelsRequest);
                    if (channelResult.isSuccess() && channelResult.getResult() != null) {
                        x.setChannelName(channelResult.getResult().getChannelName());
                    }
                }
                //调用查询货品组信息
                if (enhance && StringUtils.isNotBlank(queryInfo.getItemGroupCode())) {
                    QueryScItemGroupRequest request = new QueryScItemGroupRequest();
                    request.setCode(queryInfo.getItemGroupCode());
                    Result<ScItemGroupResponse> scItemResult = scItemGroupQueryService.getScItemGroup(request);
                    if (scItemResult.isSuccess() && scItemResult.getResult() != null) {
                        x.setItemGroupName(scItemResult.getResult().getName());
                    }
                }
                //调用查询客户送达方信息
                if (enhance && StringUtils.isNotBlank(queryInfo.getCustomerCode())) {
                    LoadCustomerAddressRequest request = new LoadCustomerAddressRequest();
                    request.setAddressCode(queryInfo.getCustomerCode());
                    CustomerAddress customerAddress = customerAddressService.loadCustomerAddress(request);
                    if (customerAddress != null) {
                        x.setCustomerName(customerAddress.getAddressName());
                    }
                }
                return x;
            }).collect(Collectors.toList());

            return result;
        } catch (Exception e) {
            log.info("creditQueryRepositoryImpl_queryCreditList_error_message={}", e);
        }
        return null;
    }

    /**
     * 查询分子公司对集团的信贷列表(分子公司可发货余额)
     * @param request
     * @return
     */
    @Override
    public Result<List<CompanyToGroupCreditResponse>> queryCompanyToGroupCreditList(QueryCompanyToGroupCreditListRequest request) {
        CreditLoadListRequest creditLoadListRequest = new CreditLoadListRequest();
        if (StringUtils.isNotBlank(request.getSoldPartCode())){
            creditLoadListRequest.setSoldPartCode(request.getSoldPartCode());
        }
        if (StringUtils.isNotBlank(request.getCompanyId())){
            creditLoadListRequest.setCompanyId(request.getCompanyId());
        }
        if (StringUtils.isNotBlank(request.getSoldPartName())){
            creditLoadListRequest.setCompanyName(request.getSoldPartName());
        }
        if (StringUtils.isNotBlank(request.getSaleOrganizationCode())){
            creditLoadListRequest.setSaleOrganizationCode(request.getSaleOrganizationCode());
        }
        if (StringUtils.isNotBlank(request.getProductGroupCode())){
            creditLoadListRequest.setProductGroupCode(request.getProductGroupCode());
        }
        if (StringUtils.isNotBlank(request.getSapChannel())){
            creditLoadListRequest.setSapChannel(request.getSapChannel());
        }
        if (request.getStart() != null){
            creditLoadListRequest.setStart(request.getStart());
        }
        if (request.getLimit() != null){
            creditLoadListRequest.setLimit(request.getLimit());
        }
        creditLoadListRequest.setDir("gmt_modified");
        creditLoadListRequest.setAsc(Boolean.FALSE);
        Result<List<Credit>> listResult = creditService.loadList(creditLoadListRequest);
        List<CompanyToGroupCreditResponse> list = Lists.newArrayList();
        if (listResult != null && CollectionUtils.isNotEmpty(listResult.getResult())){
            listResult.getResult().forEach(credit -> {
                list.add(convert(credit));
            });
        }
        return Result.listSuccess(list,listResult == null ? 0 : listResult.getTotal());
    }

    //转换成分子公司可发货余额
    private CompanyToGroupCreditResponse convert(Credit credit){
        if (credit == null){
            return null;
        }
        CompanyToGroupCreditResponse response = new CompanyToGroupCreditResponse();
        BeanUtils.copyProperties(credit,response);
        response.setCustomerActualAvailableAmountStr(credit.getCustomerActualAvailableAmount());
        //设置客户实际可发货余额的颜色
        if (StringUtils.isNotBlank(credit.getCustomerActualAvailableAmount())){
            StatusDesc statusDesc = new StatusDesc();
            statusDesc.setText(credit.getCustomerActualAvailableAmount());
            if (BigDecimal.ZERO.compareTo(new BigDecimal(credit.getCustomerActualAvailableAmount())) >= 0){
//                statusDesc.setType("error");
                statusDesc.setColor("#008000");
            }else {
//                statusDesc.setType("success");
                statusDesc.setColor("#FF0000");
            }
            response.setCustomerActualAvailableAmount(statusDesc);
        }
        return response;
    }
}
